package com.hhsjdesign.dynamicui.asm.v3


import org.objectweb.asm.*

import java.util.jar.JarEntry
import java.util.jar.JarFile

/**
 * Scan all class in the package: com/alibaba/android/arouter/
 * find out all routers,interceptors and providers
 * @author billy.qi email: qiyilike@163.com
 * @since 17/3/20 11:48
 */
class ScanUtilV3 {

    /**
     * scan jar file
     * @param jarFile All jar files that are compiled into apk
     * @param destFile dest file after this transform
     */
    static void scanJar(File jarFile, File destFile) {
        if (jarFile) {
            def file = new JarFile(jarFile)
            Enumeration enumeration = file.entries()
            //遍历jar文件中的元素
            while (enumeration.hasMoreElements()) {
                JarEntry jarEntry = (JarEntry) enumeration.nextElement()
                String entryName = jarEntry.getName()

                //如果是定义的文件名，执行asm的字节流操作,将扫描的类文件加入到指定的列表中
                if (entryName.startsWith(ScanSettingV3.DYNAMICUI_CLASS_PACKAGE_NAME)) {
                    println "jar节点下的类文件:${entryName}"
                    InputStream inputStream = file.getInputStream(jarEntry)
                    scanClass(inputStream)
                    inputStream.close()
                }

                //目标类所在的文件名,即jar包名

                if (ScanSettingV3.GENERATE_TO_CLASS_FILE_NAME == entryName) {
                    //找到了目标文件
                    println "目标注入类文件:${entryName}"

                    // mark this jar file contains LogisticsCenter.class
                    // After the scan is complete, we will generate register code into this file
                    DynamicUiTransformV3.targetAsmClass = destFile
                }
            }
            file.close()
        }
    }

    static boolean shouldProcessPreDexJar(String path) {
        return !path.contains("androidx.") && !path.contains("com.android.support") && !path.contains("/android/m2repository")
    }

    //类名
    static boolean shouldProcessClass(String entryName) {
        return entryName != null
                && entryName.endsWith(".class")
//                && (entryName.startsWith(ScanSetting.DYNAMICUI_CLASS_PACKAGE_NAME) || entryName.equals(ScanSetting.GENERATE_TO_CLASS_NAME))
    }

    /**
     * 编译成才的 .class 文件
     * scan class file
     * @param class file
     */
    static void scanClassFile(File file) {
        println "directory节点下的类文件:${file.name}"
        InputStream inputStream = new FileInputStream(file)
        scanClass(inputStream)
        inputStream.close()
    }

    /**
     * 扫描类，只是为了拿到对应的注解信息
     * @param inputStream
     */
    static void scanClass(InputStream inputStream) {

        //首先读取class
        ClassReader cr = new ClassReader(inputStream)
        //给到writer
        ClassWriter cw = new ClassWriter(cr, 0)
        //用自定义的扫描
        ScanClassVisitor cv = new ScanClassVisitor(Opcodes.ASM6, cw)
        cr.accept(cv, ClassReader.EXPAND_FRAMES)
        inputStream.close()
    }

}

